﻿using System;
using System.Web;

namespace Altairis.Web {

    public static class Cookies {

        /// <summary>
        /// Safely gets value of cookie.
        /// </summary>
        /// <param name="key1">First level cookie name.</param>
        /// <param name="key2">Second level cookie name.</param>
        /// <returns>Cookie value of empty string if not found.</returns>
        public static string Get(string key1, string key2) {
            return Get(key1, key2, string.Empty);
        }

        /// <summary>
        /// Safely gets value of cookie.
        /// </summary>
        /// <param name="key1">First level cookie name.</param>
        /// <param name="key2">Second level cookie name.</param>
        /// <param name="defaultValue">Value to be returned if cookie is not found.</param>
        /// <returns>Cookie value or defaultValue if not found.</returns>
        public static string Get(string key1, string key2, string defaultValue) {
            // Validate
            if (string.IsNullOrEmpty(key1)) throw new ArgumentNullException("key1");
            if (string.IsNullOrEmpty(key2)) throw new ArgumentNullException("key2");

            // Get cookie data
            try {
                return HttpUtility.UrlDecode(System.Web.HttpContext.Current.Request.Cookies[key1].Values[key2]);
            }
            catch {
                return defaultValue;
            }
        }

        /// <summary>
        /// Safely sets value of cookie.
        /// </summary>
        /// <param name="key1">First level cookie name.</param>
        /// <param name="key2">Second level cookie name.</param>
        /// <param name="value">The value to be set.</param>
        public static void Set(string key1, string key2, string value) {
            Set(key1, key2, value, null);
        }

        /// <summary>
        /// Safely sets value of cookie.
        /// </summary>
        /// <param name="key1">First level cookie name.</param>
        /// <param name="key2">Second level cookie name.</param>
        /// <param name="value">The value to be set.</param>
        /// <param name="daysToExpire">The number of days for cookie to expire.</param>
        public static void Set(string key1, string key2, string value, int daysToExpire) {
            Set(key1, key2, value, DateTime.Now.AddDays(daysToExpire));
        }

        /// <summary>
        /// Safely sets value of cookie.
        /// </summary>
        /// <param name="key1">First level cookie name.</param>
        /// <param name="key2">Second level cookie name.</param>
        /// <param name="value">The value to be set.</param>
        /// <param name="expiration">The cookie expiration time or <c>null</c> for session cookie.</param>
        public static void Set(string key1, string key2, string value, DateTime? expiration) {
            if (string.IsNullOrEmpty(key1)) throw new ArgumentNullException("key1");
            if (string.IsNullOrEmpty(key2)) throw new ArgumentNullException("key2");
            if (value == null) throw new ArgumentNullException("value");
            value = HttpUtility.UrlEncode(value);

            // Set cookie
            HttpCookie c = System.Web.HttpContext.Current.Request.Cookies[key1];
            if (c == null) {
                c = new HttpCookie(key1);
                c.Values.Add(key2, value);
            }
            else {
                if (Array.IndexOf<string>(c.Values.AllKeys, key2) == -1) {
                    c.Values.Add(key2, value);
                }
                else {
                    c.Values[key2] = value;
                }
            }
            if (expiration.HasValue) c.Expires = expiration.Value;
            System.Web.HttpContext.Current.Response.Cookies.Add(c);
        }
    }
}